package com.bnuz.vtl.controller;

import com.bnuz.vtl.model.PrivateNode;
import com.bnuz.vtl.model.PublicNode;
import com.bnuz.vtl.model.User;
import com.bnuz.vtl.service.PrivateNodeService;
import com.bnuz.vtl.service.PublicNodeService;
import com.bnuz.vtl.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.List;

@RequestMapping("/api/node")
@RestController
public class NodeController {

    @Autowired
    private PrivateNodeService privateNodeService;
    @Autowired
    private PublicNodeService publicNodeService;
    @Autowired
    private UserService userService;

    @PostMapping("/privateNode")
    public PrivateNode savePrivateNode(@RequestBody PrivateNode privateNode) {
        return privateNodeService.save(privateNode);
    }

    @DeleteMapping("/privateNode/{privateNodeId}")
    public void deletePrivateNode(@PathVariable String privateNodeId) {
        privateNodeService.deleteById(privateNodeId);
    }

    @PutMapping("/privateNode}")
    public void updatePrivateNode(@RequestBody PrivateNode parent) {
        privateNodeService.updateWithNewChildren(parent);
    }

    @GetMapping("/privateNode/{privateNodeId}")
    public PrivateNode findPrivateNodeById(@PathVariable String privateNodeId) {
        return privateNodeService.findById(privateNodeId);
    }

    @GetMapping("/privateNode")
    public List<PrivateNode> findAllPrivateNode() {
        return privateNodeService.findAll();
    }

    @GetMapping("/privateNode/{privateNodeId}/{depth}")
    public PrivateNode findPrivateNodeById(@PathVariable String privateNodeId, @PathVariable int depth) {
        return privateNodeService.findById(privateNodeId, depth);
    }

    @GetMapping("/privateNode/{privateNodeId}/tree")
    public PublicNode getPrivateNodeTree(@PathVariable String privateNodeId) {
        return privateNodeService.getParent(privateNodeId);
    }

    @GetMapping("/publicNode/{publicNodeId}/tree")
    public PublicNode getPublicNodeTree(@PathVariable String publicNodeId) {
        return publicNodeService.getParent(publicNodeId);
    }

    // Merge
    @GetMapping("/privateNode/merge/{publicNodeId}/{childName}")
    public void mergePrivateNode(@PathVariable String publicNodeId, @PathVariable String childName) {
        privateNodeService.merge(publicNodeId, childName);
    }

    @PostMapping("/publicNode")
    public PublicNode savePublicNode(@RequestBody PublicNode publicNode) {
        return publicNodeService.save(publicNode);
    }

    @DeleteMapping("/publicNode/{publicNodeId}")
    public void deletePublicNode(@PathVariable("publicNodeId") String publicNodeId) {
        publicNodeService.deleteById(publicNodeId);
    }

    @GetMapping("/publicNode")
    public List<PublicNode> findAllPublicNode() {
        return publicNodeService.findAll();
    }

    @GetMapping("/publicNode/{publicNodeId}")
    public PublicNode findPublicNodeById(@PathVariable("publicNodeId") String publicNodeId) {
        return publicNodeService.findById(publicNodeId);
    }

    @GetMapping("/publicNode/{publicNodeId}/{depth}")
    public PublicNode findPublicNodeById(@PathVariable String publicNodeId, @PathVariable int depth) {
        return publicNodeService.findById(publicNodeId, depth);
    }

    @PostMapping("/create/publicNode/{publicNodeId}")
    public PrivateNode insertNodeAsPublicNodeChildren(Principal user, @PathVariable String publicNodeId, @RequestBody PrivateNode privateNode) {
        User _user = userService.findByUsername(user.getName());
        privateNode.setOwner(_user);
        return privateNodeService.saveNodeAsPublicNodeChildren(publicNodeId, privateNode);
    }

    @PostMapping("/create/privateNode/{privateNodeId}")
    public PrivateNode insertNodeAsPrivateNodeChildren(Principal user, @PathVariable String privateNodeId, @RequestBody PrivateNode privateNode) {
        privateNode.setOwner(userService.findByUsername(user.getName()));
        return privateNodeService.saveNodeAsPrivateNodeChildren(privateNodeId, privateNode);
    }


}
